using System;
using UnityEditor;
using UnityEngine;


namespace HEFramework
{
    /// <summary>
    ///
    /// 表格设置编辑器
    /// 
    /// ----------------------------------------
    /// 作者 hep
    /// 创建时间：2024-01-16 18:21:37
    /// ----------------------------------------
    /// </summary>
    public class DataTableSettingScriptableObjectEditor : EditorWindow
    {
        private static string templatePath = @"Assets/Resources/DataTableTemplate.asset";

        private const int NAME_LENGTH = 120;
        private const int VALUE_LENGTH = 350;
        private const int NAME_HEIGHT = 18;
        private const int HELP_LENGTH = 475;


        private DataTableSettingScriptableObject data;
        private GUILayoutOption[] nameOptions;
        private GUILayoutOption[] valueOptions;

        /// <summary>
        /// 打开编辑面板时初始化
        /// </summary>
        private void Awake()
        {
            data = DataTableSettingScriptableObject.Instance;
            nameOptions = new[] { GUILayout.Width(NAME_LENGTH), GUILayout.Height(NAME_HEIGHT) };
            valueOptions = new[] { GUILayout.Width(VALUE_LENGTH), GUILayout.Height(NAME_HEIGHT) };
        }


        public static void OpenSettingsWindow()
        {
            try
            {
                if (EditorApplication.isCompiling)
                {
                    return;
                }

                var window = GetWindowWithRect<DataTableSettingScriptableObjectEditor>(new Rect(0, 0, 520, 800), true, "DataTable Setting", true);
                window.Show();
            }
            catch (Exception e)
            {
                Debug.Log(e.Message);
            }
        }


        private void OnGUI()
        {
            DataTableGUIStyle.Ensure();

            if (data == null)
            {
                Debug.LogError("Setting data is none.");
            }

            GUILayout.BeginHorizontal();
            GUILayout.Space(5);
            GUILayout.Label("表格数据设置", DataTableGUIStyle.LargeLabel);
            GUILayout.Space(5);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();

            if (GUILayout.Button("导出", GUILayout.Width(80), GUILayout.Height(20)))
            {
                Export();
            }

            if (GUILayout.Button("删除脚本", GUILayout.Width(80), GUILayout.Height(20)))
            {
                ClearFile(data.SaveCodePath);
            }

            if (GUILayout.Button("删除数据", GUILayout.Width(80), GUILayout.Height(20)))
            {
                ClearFile(data.SaveDataPath);
            }

            if (GUILayout.Button("创建模版", GUILayout.Width(80), GUILayout.Height(20)))
            {
                DataTableTemplate.Create(templatePath);
            }
            
            if (GUILayout.Button("打开表目录", GUILayout.Width(80), GUILayout.Height(20)))
            {
                if (System.IO.Directory.Exists(data.DataTablePath))
                {
                    EditorUtility.RevealInFinder(data.DataTablePath); // 打开文件夹
                }
            }
            
            if (GUILayout.Button("重置全部", GUILayout.Width(80), GUILayout.Height(20)))
            {
                if (EditorUtility.DisplayDialog("TableTool", "Are you sure to reset all settings?", "Yes", "Cancel"))
                {
                    //数据重置
                    DataTableSettingScriptableObject.Instance.ResetAll();
                    EditorUtility.SetDirty(DataTableSettingScriptableObject.Instance);
                }
            }

            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("表格目录路径", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("路径", DataTableGUIStyle.Label, nameOptions);
            data.DataTablePath = EditorGUILayout.TextField(data.DataTablePath, DataTableGUIStyle.TextField, valueOptions);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("数据存储路径", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("路径", DataTableGUIStyle.Label, nameOptions);
            data.SaveDataPath = EditorGUILayout.TextField(data.SaveDataPath, DataTableGUIStyle.TextField, valueOptions);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("脚本存储路径", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("路径", DataTableGUIStyle.Label, nameOptions);
            data.SaveCodePath = EditorGUILayout.TextField(data.SaveCodePath, DataTableGUIStyle.TextField, valueOptions);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("导出Key存储路径", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("路径", DataTableGUIStyle.Label, nameOptions);
            data.SaveOutputKeyPath = EditorGUILayout.TextField(data.SaveOutputKeyPath, DataTableGUIStyle.TextField, valueOptions);
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("是否替换换行符以及回车符", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("开关", DataTableGUIStyle.Label, nameOptions);
            data.IsReplaceTableAndEnterChar = GUILayout.Toggle(data.IsReplaceTableAndEnterChar, "");
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("忽略以此为开始的文件", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("标识", DataTableGUIStyle.Label, nameOptions);
            data.IgnoreFileWhenStartWith = EditorGUILayout.TextField(data.IgnoreFileWhenStartWith, DataTableGUIStyle.TextField, valueOptions);
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("忽略以此为开始的Sheet表格", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("标识", DataTableGUIStyle.Label, nameOptions);
            data.IgnoreSheetWhenStartWith = EditorGUILayout.TextField(data.IgnoreSheetWhenStartWith, DataTableGUIStyle.TextField, valueOptions);
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("是否忽略以'#'为开头的列", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("开关", DataTableGUIStyle.Label, nameOptions);
            data.IsIgnoreColumnWhichFirstRowIsHashTag = GUILayout.Toggle(data.IsIgnoreColumnWhichFirstRowIsHashTag, "");
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("是否忽略以'#'为开头的行", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("开关", DataTableGUIStyle.Label, nameOptions);
            data.IsIgnoreRowWhichFirstColumnIsHashTag = GUILayout.Toggle(data.IsIgnoreRowWhichFirstColumnIsHashTag, "");
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("是否忽略空开头的行", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("开关", DataTableGUIStyle.Label, nameOptions);
            data.IsIgnoreRowWhichFirstPropertyIsEmpty = GUILayout.Toggle(data.IsIgnoreRowWhichFirstPropertyIsEmpty, "");
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("设置导出行", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("下标", DataTableGUIStyle.Label, nameOptions);
            data.PropertySettingRow = Int32.Parse(EditorGUILayout.TextField(data.PropertySettingRow.ToString(), DataTableGUIStyle.TextField, valueOptions));
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("名字导出行", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("下标", DataTableGUIStyle.Label, nameOptions);
            data.PropertyNameRow = Int32.Parse(EditorGUILayout.TextField(data.PropertyNameRow.ToString(), DataTableGUIStyle.TextField, valueOptions));
            GUILayout.EndHorizontal();


            GUILayout.BeginHorizontal();
            GUILayout.Label("类型导出行", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("下标", DataTableGUIStyle.Label, nameOptions);
            data.PropertyTypeRow = Int32.Parse(EditorGUILayout.TextField(data.PropertyTypeRow.ToString(), DataTableGUIStyle.TextField, valueOptions));
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("节点导出行", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("下标", DataTableGUIStyle.Label, nameOptions);
            data.PropertyNoteRow = Int32.Parse(EditorGUILayout.TextField(data.PropertyNoteRow.ToString(), DataTableGUIStyle.TextField, valueOptions));
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("数据开始行", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("下标", DataTableGUIStyle.Label, nameOptions);
            data.PropertyStartRow = Int32.Parse(EditorGUILayout.TextField(data.PropertyStartRow.ToString(), DataTableGUIStyle.TextField, valueOptions));
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            GUILayout.Label("数组符号", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("符号", DataTableGUIStyle.Label, nameOptions);
            data.PropertyArrEndWith = EditorGUILayout.TextField(data.PropertyArrEndWith, DataTableGUIStyle.TextField, valueOptions);
            GUILayout.EndHorizontal();
            
            GUILayout.BeginHorizontal();
            GUILayout.Label("数组数据分隔符号", DataTableGUIStyle.HelpBox, GUILayout.Width(HELP_LENGTH));
            GUILayout.EndHorizontal();
            GUILayout.BeginHorizontal();
            GUILayout.Label("符号", DataTableGUIStyle.Label, nameOptions);
            string s = EditorGUILayout.TextField(data.PropertyArrSplitChar.ToString(), DataTableGUIStyle.TextField, valueOptions);
            if (s.Length > 0)
            {
                data.PropertyArrSplitChar = s[0];
            }
            GUILayout.EndHorizontal();
        }


        /// <summary>
        /// 导出
        /// </summary>
        private static void Export()
        {
            DataTableLog.Reset();

            // 加载配置
            DataTableTemplate.Load(templatePath);

            // 处理文件
            if (!DataTableLog.ErrorFlag)
            {
                DataTableExportor e = new DataTableExportor();
                e.PrecessFiles();
            }

            // 结束
            if (DataTableLog.ErrorFlag)
            {
                DataTableLog.PrintError("处理失败");
            }
            else
            {
                DataTableLog.PrintLog("处理完成");
            }

            // 打印
            if (DataTableLog.ErrorFlag)
            {
                EditorUtility.DisplayDialog("Exporter Error", string.Join('\n', DataTableLog.GetMsg(true)), "ok");
            }
            else if (DataTableSettingScriptableObject.Instance.IsLogDetail)
            {
                EditorUtility.DisplayDialog("Exporter", string.Join('\n', DataTableLog.GetMsg(false)), "ok");
            }

            // 刷新
            AssetDatabase.Refresh();
        }


        /// <summary>
        /// 清除文件夹下的所有文件
        /// </summary>
        /// <param name="_dirPath"></param>
        private static void ClearFile(string _dirPath)
        {
            DirectoryDelete(_dirPath);
            EditorUtility.DisplayDialog("Exporter Clear", "清除文件成功,path:" + _dirPath, "ok");
            AssetDatabase.Refresh();
        }


        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="_path"></param>
        /// <returns></returns>
        private static bool DirectoryDelete(string _path)
        {
            try
            {
                // 确保目录存在
                if (System.IO.Directory.Exists(_path))
                {
                    // 删除目录中的所有文件
                    string[] files = System.IO.Directory.GetFiles(_path);
                    foreach (string file in files)
                    {
                        System.IO.File.SetAttributes(file, System.IO.FileAttributes.Normal); // 将文件属性设置为正常，确保文件不是只读
                        System.IO.File.Delete(file);
                    }

                    // 递归删除所有子目录
                    string[] subDirs = System.IO.Directory.GetDirectories(_path);
                    foreach (string subDir in subDirs)
                    {
                        DirectoryDelete(subDir);
                    }

                    // 删除现在空的目录
                    System.IO.Directory.Delete(_path, true);
                }
            }
            catch (Exception e)
            {
                return false;
            }
#if UNITY_EDITOR
            UnityEditor.AssetDatabase.Refresh();
#endif

            if (System.IO.File.Exists(_path + ".meta"))
            {
                System.IO.File.Delete(_path + ".meta");
            }

#if UNITY_EDITOR
            UnityEditor.AssetDatabase.Refresh();
#endif

            return true;
        }
    }
}